/* 
function addGen03<T>(a: T, b: T) {
  return a + b;     // 报错 不能使用+运算符 因为实参可能是undefined null NaN等等
}

addGen03(1, 2);

function addGen04<T>(a: T) {
  return a.length;     // 报错 不能指定长度 因为实参可能是undefined null NaN等等
}

addGen04(undefined);
*/

// 在类型后面跟一个extends 再跟一个约束的类型
function addGen03<T extends number>(a: T, b: T) {
  return a + b;     // 报错 不能使用+运算符 因为实参是undefined null NaN等等
}

addGen03(1, 2);


interface Len {
  length: number;
}
function addGen04<T extends Len>(a: T) {
  a.length;     // 报错 不能指定长度 因为实参可能是undefined null NaN等等
}

addGen04('111111');
addGen04([1,2,3,4,5]);

// 对象中使用泛型
let objGen01 = {
  name: "小李",
  sex: "男"
}

// type keyGen01 = keyof typeof objGen01;  // keyGen01 = "name" | "sex" 举例说明

function ob01<T extends object, K extends keyof T> (obj: T, key: K) {
  return obj[key];
}

// ob01(objGen01, "age"); // 报错 age不存在
ob01(objGen01, "name");

interface genData {
  name: string,
  age: number,
  sex: string
}

// for in for(let key in obj)
type OptionsObjGen<T extends object> = {
  readonly [Key in keyof T]?: T[Key]
}

type objGen = OptionsObjGen<genData>;
